﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Input.Touch;
using Microsoft.Xna.Framework.Media;

namespace GameWP
{
    public class ManagerZombie
    {
#region Properties
        private List<AutoCharacter> _listAllZombies;

        private List<AutoCharacter> _listZombiesNow;
        public List<AutoCharacter> ListZombiesNow
        {
            get { return _listZombiesNow; }
            set { _listZombiesNow = value; }
        }

        private int _levelWave;
        public int LevelWave
        {
            get { return _levelWave; }
            set { _levelWave = value; }
        }

        private SpriteFont _font;
        public SpriteFont Font
        {
            get { return _font; }
            set { _font = value; }
        }

        private int _numWave;
        public int NumWave
        {
            get { return _numWave; }
            set { _numWave = value; }
        }

        private Button _waveButton;
        private int _levelScreen;
        private List<List<List<int>>> ListZombieConst;
        
#endregion

#region Initilation
        public ManagerZombie(List<AutoCharacter> listAllZombies, SpriteFont font)
        {
            _listAllZombies = listAllZombies;
            _listZombiesNow = new List<AutoCharacter>();
            _numWave = 10;
            _levelWave = 0;
            _font = font;
            _waveButton = new Button(_levelWave.ToString(), _font, new Vector2(350, 25)) { HaveAnimation = false };

            //Tao zombie cho canh
            GeneralZombie();
        }
#endregion

#region Methods
        public AutoCharacter CreateZombie(int level)
        {
            //level tuong ung voi bowzombie: 1,2,8,11,13
            AutoCharacter NewZombie;
            switch (level)
            {
                case 1: case 2: case 8: case 15: case 13:
                    return NewZombie = new BowZombie(_listAllZombies[level].ListTextures,
                        _listAllZombies[level].Position, _listAllZombies[level].PositionBullet,
                        _listAllZombies[level].Hp, _listAllZombies[level].Damage, _listAllZombies[level].Speed,
                        _listAllZombies[level].ScaleRect, _listAllZombies[level].Delay, _listAllZombies[level].ScaleTexture,
                        _listAllZombies[level].Price, _listAllZombies[level].SpriteEffect, _listAllZombies[level].SeqTexture);
                case 9:
                    return NewZombie = new DoctorZombie(_listAllZombies[level].ListTextures,
                        _listAllZombies[level].Position, _listAllZombies[level].PositionBullet,
                        _listAllZombies[level].Hp, _listAllZombies[level].Damage, _listAllZombies[level].Speed,
                        _listAllZombies[level].ScaleRect, _listAllZombies[level].Delay, _listAllZombies[level].ScaleTexture,
                        _listAllZombies[level].Price, _listAllZombies[level].SpriteEffect, _listAllZombies[level].SeqTexture);
                default:
                    if (level < 15 && level >= 0)
                        return NewZombie = new SwordZombie(_listAllZombies[level].ListTextures,
                        _listAllZombies[level].Position, _listAllZombies[level].Hp, _listAllZombies[level].Damage, _listAllZombies[level].Speed,
                        _listAllZombies[level].Delay, _listAllZombies[level].ScaleTexture, _listAllZombies[level].Price,
                        _listAllZombies[level].SpriteEffect, _listAllZombies[level].SeqTexture) { OnlyAttackTresure = _listAllZombies[level].OnlyAttackTresure };
                    break;
            }

            return null;
        }

        public void SwapZombie (int level)
        {
            _listZombiesNow.Add(CreateZombie(level));
            _listZombiesNow[_listZombiesNow.Count - 1].Position = 
                new Vector2(_listZombiesNow[_listZombiesNow.Count - 1].Position.X+ ManagerGame.rand.Next(-50, 150), _listZombiesNow[_listZombiesNow.Count - 1].Position.Y);
        }

        public void SwapListZombie(int wave)
        {
            for (int i = 0; i < ListZombieConst[_levelScreen][_levelWave].Count; i++)
            {
                SwapZombie(ListZombieConst[_levelScreen][_levelWave][i]);
                if (!ManagerGame.LevelNormal)   //Nghia la chon difficlut, thi so luong zombie se gap doi
                    SwapZombie(ListZombieConst[_levelScreen][_levelWave][i]);
            }
        }

        public void ResetAtLevelScreen(int leveScreen)
        {
            _listZombiesNow.Clear();
            _levelScreen = ManagerGame.luffy.LevelScreen;
            _levelWave = -1;
        }
#endregion

#region Update & Draw
        public void ManageUpdate(GameTime gametime)
        {            
            if (_listZombiesNow.Count <= 0)
            {
                _levelWave ++;
                if (_levelWave >= _numWave)
                    return;
                SwapListZombie(_levelWave);
            }
            _waveButton.Text = _levelScreen.ToString() +" - Wave: " + _levelWave.ToString() + "/" + _numWave.ToString();
            for (int i = 0; i < _listZombiesNow.Count; i++)
            {
                if (_listZombiesNow[i].State == State.Disappear)
                {
                    ManagerGame.luffy.Balance += (_listZombiesNow[i].Price * 3);
                    _listZombiesNow.RemoveAt(i);                    
                }
                else
                    _listZombiesNow[i].Update(gametime, Vector2.Zero);
            }
        }

        public void ManageDraw(SpriteBatch spritebatch, GameTime gametime)
        {
            for (int i = 0; i < _listZombiesNow.Count; i++)
                _listZombiesNow[i].Draw(spritebatch, gametime);
        }

        public void ManageDrawConst(SpriteBatch spritebatch, GameTime gametime)
        {
            _waveButton.Draw(spritebatch, gametime);
        }
#endregion

#region General Zombie
        private void GeneralZombie()
        {
            int indexZombie, preindexZombie;
            ListZombieConst = new List<List<List<int>>>();
            int numScreen = 13;
            // so canh choi
            for (int iScreen = 0; iScreen < numScreen; iScreen++)                
            {
                List<List<int>> Screen = new List<List<int>>();
                // so wave cua 1 canh mac dinh gia tri la 10
                for (int iWave = 0; iWave < _numWave; iWave++)
                {
                    List<int> Wave = new List<int>();
                    int numZombieInWave = (int)(Math.Pow(1.3, iScreen) * Math.Pow(1.1, iWave));
                    int midnumZombieInWave = (int)(numZombieInWave / 2);
                    int start = 0;
                    int end = iScreen + 3;
                    preindexZombie = -1;
                    indexZombie = -1;
                    for (int iZombie = 0; iZombie < numZombieInWave; iZombie++)
                    {
                        if (iZombie < midnumZombieInWave || midnumZombieInWave == 0) { start = 0; end = (int)((iScreen + 3) / 2); }
                        else { start = (int)((iScreen + 3) / 2); end = iScreen + 3; };

                        while (indexZombie == preindexZombie)
                            indexZombie = ManagerGame.rand.Next(start, end);
                        Wave.Add(indexZombie);
                        preindexZombie = indexZombie;
                    }
                    if (iWave == 9) Wave.Add(iScreen + 4);
                    Screen.Add(Wave);
                }
                ListZombieConst.Add(Screen);
            }
        }
#endregion
    }
}
